﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace MetaSharp.Transformation.Patterns
{
    public class AndPattern : Pattern
    {
        public IEnumerable<Pattern> Patterns { get; private set; }
        public AndPattern(IEnumerable<Pattern> patterns)
            : base(PatternKind.And)
        {
            this.Patterns = patterns;
        }

        public override PatternMatch Compile()
        {
            var patterns = new List<PatternMatch>();
            foreach (var pattern in Patterns)
                patterns.Add(pattern.Compile());

            return s => Target(s, patterns);
        }

        private static async Task<IMatch> Target(IScope scope, IList<PatternMatch> patterns)
        {
            var end = scope;
            var errors = new ArrayList<Error>();
            var values = new object[patterns.Count];
            for (int x = 0; x < patterns.Count; x++)
            {
                var match = await patterns[x](end);
                if (!match.Matched)
                {
                    match = match.SetEnd(scope.SetMemos(end.Memos));
                    return match;
                }

                end = match.End;
                values[x] = match.Value;
                errors.AddRange(match.Errors);
            }

            return new Match(values, scope, end, errors);
        }
    }
}
